#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int main() {
	key_t key;
	int pid, val, semid;

	key = ftok(".", 's');

	if ((semid=semget(key, 1, IPC_CREAT|0700)) < 0) {
		printf("semget error: %s\n", strerror(errno));
		return -1;
	}

	printf("%d\n", semid);
	val = 1;
	if (semctl(semid, 0, SETVAL, val) < 0) {
		printf("semctl error: %s\n", strerror(errno));
		return -1;
	}

	if ((pid=fork()) < 0) {	
		printf("fork error: %s\n", strerror(errno));
		return -1;
	}
	else if (pid > 0) {
		struct sembuf p_op_buf, v_op_buf;
		p_op_buf.sem_num = 0;
		p_op_buf.sem_op = -1;
		p_op_buf.sem_flg = 0;
		if (semop(semid, &p_op_buf, 1) < 0) {	
			printf("semop error: %s\n", strerror(errno));
			return -1;
		}
		else {
			int i;
			printf("get semphore\n");
			sleep(6);

			v_op_buf.sem_num = 0;
			v_op_buf.sem_op = 1;
			v_op_buf.sem_flg = 0;
			if ((semop(semid, &v_op_buf, 1)) < 0) {					
				printf("fork error: %s\n", strerror(errno));
				return -1;
			}
			else {	
				printf("rel semphore\n");
				sleep(1);
			}
		}
	}
	else {
		struct sembuf p_op_buf, v_op_buf;
		sleep(2);

		p_op_buf.sem_num = 0;
		p_op_buf.sem_op = -1;
		p_op_buf.sem_flg = 0;
		if (semop(semid, &p_op_buf, 1) < 0) {	
			printf("c semop error: %s\n", strerror(errno));
			return -1;
		}
		else {
			int i;
			printf("c get semphore\n");
			sleep(60);

			v_op_buf.sem_num = 0;
			v_op_buf.sem_op  = 1;
			v_op_buf.sem_flg = 0;
			if ((semop(semid, &v_op_buf, 1)) < 0) {					
				printf("c fork error: %s\n", strerror(errno));
				return -1;
			}
			else {	
				if (semctl(semid, 0, IPC_RMID, 0) < 0)	{				
					printf("c semctl error: %s\n", strerror(errno));
					return -1;
				}
				else {
					printf("c remove semphore\n");
					return -1;
				}
			}
		}
	}

	return 0;
}